package com.zc.gateway.security.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zc.commons.auth.dto.CurrentAuthUser;
import com.zc.commons.auth.dto.LoginSuccessResult;
import com.zc.commons.auth.dto.LoginUserDetails;
import com.zc.commons.auth.pojo.SystemRole;
import com.zc.commons.http.entity.Response;
import com.zc.gateway.jwt.JsonWebJwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * 登录成功处理器
 *
 * @author zcj
 * @version 1.0.0
 * @date 2022/1/6 16:59
 */
@Component
public class LoginSuccessHandler implements ServerAuthenticationSuccessHandler {

    @Autowired
    private JsonWebJwtService jsonWebJwtService;

    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
        response.setStatusCode(HttpStatus.OK);
        HttpHeaders headers = response.getHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        LoginUserDetails principal = (LoginUserDetails) authentication.getPrincipal();
        // 包装用户信息和角色信息返回
        LoginSuccessResult result = new LoginSuccessResult();
        result.setUserDetails(principal);
        result.setToken(generateUserToken(principal));
        Response<LoginSuccessResult> data = Response.ok(result);
        DataBuffer buffer = response.bufferFactory().wrap(JSON.toJSONString(data, SerializerFeature.WriteMapNullValue).getBytes());
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 生成用户token
     *
     * @param userDetails
     * @return
     */
    private String generateUserToken(LoginUserDetails userDetails) {
        CurrentAuthUser user = new CurrentAuthUser();
        user.setId(userDetails.getId());
        user.setTenantId(userDetails.getTenantId());
        user.setAccount(userDetails.getAccount());
        user.setName(userDetails.getUsername());
        user.setOrgId(userDetails.getOrgId());
        Set<String> roles = userDetails.getRoles().stream().map(SystemRole::getRoleCode).collect(Collectors.toSet());
        user.setRoles(roles);
        return jsonWebJwtService.generateJwtToken(user, false);
    }


}
